package com.springboot.cli.utils;

import org.docx4j.jaxb.Context;
import org.docx4j.model.structure.SectionWrapper;
import org.docx4j.model.table.TblFactory;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.wml.*;

import java.io.File;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * description:
 *
 * @author huxingjie
 * @date 2023/11/7 18:59
 */
public class DocxUtil {

    static org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();

    WordprocessingMLPackage wordMLPackage;

    int writableWidthTwips;

    List contents = new LinkedList();

    public DocxUtil() throws InvalidFormatException {
        this.wordMLPackage = WordprocessingMLPackage.createPackage();
        this.writableWidthTwips = this.wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
    }

    public void createWord(String path) {
        this.contents.forEach((o) -> {
            this.wordMLPackage.getMainDocumentPart().getContent().add(o);
        });
        Style headingStyle = this.wordMLPackage.getMainDocumentPart().getStyleDefinitionsPart().getStyleById("Heading1");
        RPr rpr = headingStyle.getRPr();
        if (rpr == null) {
            rpr = new RPr();
            headingStyle.setRPr(rpr);
        }
        HpsMeasure fontSize = new HpsMeasure();
        fontSize.setVal(BigInteger.valueOf(50L));
        rpr.setSz(fontSize);
        try {
            this.wordMLPackage.save(new File(path));
        } catch (Docx4JException var6) {
            var6.printStackTrace();
        }
    }

    public R addH(String text, int lv,long numId, long ilvl) {
        P p = new P();
        Text t = new Text();
        t.setValue(text);
        R r = new R();
        r.getContent().add(t);
        p.getContent().add(r);
        PPr pPr = new PPr();
        PPrBase.PStyle style = new PPrBase.PStyle();
        style.setVal("Heading" + lv);
        pPr.setPStyle(style);


        // Create and add <w:numPr>
        PPrBase.NumPr numPr =  new PPrBase.NumPr();
        pPr.setNumPr(numPr);

        // The <w:ilvl> element
        PPrBase.NumPr.Ilvl ilvlElement = new PPrBase.NumPr.Ilvl();
        numPr.setIlvl(ilvlElement);
        ilvlElement.setVal(BigInteger.valueOf(ilvl));

        // The <w:numId> element
        PPrBase.NumPr.NumId numIdElement = factory.createPPrBaseNumPrNumId();
        numPr.setNumId(numIdElement);
        numIdElement.setVal(BigInteger.valueOf(numId));


        p.setPPr(pPr);
        this.contents.add(p);
        return r;
    }

    public P createP() {
        P p = new P();
        this.contents.add(p);
        return p;
    }

    public static R addRun(P p, String text) {
        R r = new R();
        Text t = new Text();
        t.setValue(text);
        r.getContent().add(t);
        p.getContent().add(r);
        return r;
    }

    public R addP(String text) {
        P p = new P();
        Text t = new Text();
        t.setValue(text);
        R r = new R();
        r.getContent().add(t);
        p.getContent().add(r);
        this.contents.add(p);
        return r;
    }

    public Tbl addTable(List<List<String>> data) {
        int col = data.get(0).size();
        int width = this.writableWidthTwips / col;
        Tbl tbl = TblFactory.createTable(data.size(), col, width);
        List<Object> rows = tbl.getContent();
        for (int i = 0; i < rows.size(); ++i) {
            Tr tr = (Tr) rows.get(i);
            List<Object> cells = tr.getContent();
            for (int j = 0; j < col; ++j) {
                Tc td = (Tc) cells.get(j);
                P p = new P();
                Text t = new Text();
                t.setValue((String) ((List) data.get(i)).get(j));
                R r = new R();
                if (i == 0) {
                    Color color = new Color();
                    color.setVal("#00aa00");
                    RPr rPr = new RPr();
                    rPr.setColor(color);
                    BooleanDefaultTrue b = new BooleanDefaultTrue();
                    rPr.setB(b);
                    r.setRPr(rPr);
                }
                r.getContent().add(t);
                p.getContent().add(r);
                td.getContent().add(p);
            }
        }
        this.contents.add(tbl);
        return tbl;
    }

    public static void setColor(R run, String fontColor) {
        Color color = new Color();
        color.setVal(fontColor);
        RPr rPr = getRPr(run);
        rPr.setColor(color);
        run.setRPr(rPr);
    }

    public static void setSize(R run, String fontSize) {
        RPr rPr = getRPr(run);
        HpsMeasure size = new HpsMeasure();
        size.setVal(new BigInteger(fontSize));
        rPr.setSz(size);
        rPr.setSzCs(size);
        run.setRPr(rPr);
    }

    public static void setHighLight(R run, String color) {
        Highlight highlight = new Highlight();
        highlight.setVal(color);
        RPr rPr = getRPr(run);
        rPr.setHighlight(highlight);
        run.setRPr(rPr);
    }

    private static RPr getRPr(R run) {
        return run.getRPr() == null ? new RPr() : run.getRPr();
    }

    public static void main(String[] args) throws InvalidFormatException {
        DocxUtil docxUtil = new DocxUtil();
        docxUtil.addP("这是一段文字");
        R run = docxUtil.addP("第二段文字");
        setHighLight(run, DocxUtil.highLightColors.green.name());
        setSize(run, "50");
        run = docxUtil.addH("标题", 1,1,0);
        setColor(run, "#00ff00");
        setHighLight(run, DocxUtil.highLightColors.yellow.name());
        docxUtil.addH("标题2.1", 2,1,0);
        docxUtil.addH("标题2.2", 2,1,0);
        docxUtil.addH("标题2.3", 2,1,0);
        docxUtil.addH("标题3", 3,1,0);
        List<List<String>> list = new ArrayList();
        for (int i = 0; i < 8; ++i) {
            List<String> list2 = new ArrayList();
            for (int j = 0; j < 4; ++j) {
                list2.add("阿汉擦边");
            }
            list.add(list2);
        }
        docxUtil.addTable(list);
        docxUtil.createWord("D:/test.docx");
    }

    public static enum highLightColors {
        yellow,
        green,
        red;

        private highLightColors() {
        }
    }
}
